// 导入WMS打印服务客户端
import WMSPrinter from './wms-printer';
import { ElMessage, ElLoading } from 'element-plus';
import printJS from 'print-js';
import CanvasRenderer from './canvasRenderer';
import 'print-js/dist/print.css';
/**
 * 打印服务封装类
 * 集成了与Electron打印和图片打印相关的所有功能
 */
class PrintService {
  constructor() {
    this.isElectronAvailable = false;
    this.defaultPrinter = '';
    this.printerList = [];
    this.eventListeners = [];
    this.canvasRenderer = new CanvasRenderer();
    this.showPrinterDialog = null; // 将由外部组件提供显示打印机选择对话框的方法
    this.isPrinting = false;
    // 添加初始化和事件监听标志
    this.isInitialized = false;
    this.isEventListenersSetup = false;
  }

  setCanvasRenderer(canvasRenderer){
    this.canvasRenderer = canvasRenderer;
  }

  getCanvasRenderer(){
    return this.canvasRenderer;
  }

  /**
   * 初始化打印服务
   * @returns {Promise<boolean>} 打印服务是否可用
   */
  async init() {
    // 如果已经初始化成功，直接返回状态
    if (this.isInitialized && this.isElectronAvailable) {
      console.log('打印服务已经初始化，跳过重复初始化');
      return true;
    }
    
    try {
      // 从localStorage加载默认打印机
      this.loadDefaultPrinter();
      
      // 设置打印服务降级处理
      this.setFallbackHandler();
      
      // 检查打印服务是否可用
      const printers = await WMSPrinter.getPrinters();
      this.isElectronAvailable = true;
      this.isInitialized = true;
      console.log('Electron打印服务可用，检测到打印机数量:', printers.length);
      return true;
    } catch (error) {
      this.isElectronAvailable = false;
      console.log('Electron打印服务不可用:', error);
      
      // 如果是连接错误，可能是端口问题
      if (error.message && (
        error.message.includes('connection') || 
        error.message.includes('WebSocket') ||
        error.message.includes('连接')
      )) {
        // 触发连接失败事件，应用可以监听此事件显示端口设置对话框
        this._triggerEvent('printServiceConnectionFailed', { error });
      }
      
      // 移除5秒后自动重连的逻辑，由用户决定是否重新连接
      
      return false;
    }
  }

  getIsInitialized(){
    return this.isInitialized;
  }

  /**
   * 从localStorage加载默认打印机
   * @returns {string} 默认打印机名称
   */
  loadDefaultPrinter() {
    const printer = localStorage.getItem('defaultPrinter');
    this.defaultPrinter = printer || '';
    return this.defaultPrinter;
  }

  /**
   * 保存默认打印机
   * @param {string} printerName - 打印机名称
   */
  saveDefaultPrinter(printerName) {
    if (!printerName) return;
    
    this.defaultPrinter = printerName;
    localStorage.setItem('defaultPrinter', printerName);
    WMSPrinter.setDefaultPrinter(printerName);
  }

  /**
   * 设置打印服务降级处理
   */
  setFallbackHandler() {
    WMSPrinter.setFallbackHandler((pdfBlob, printerName, options) => {
      console.log('Electron打印不可用，使用浏览器原生打印');
      // 创建临时URL
      const url = URL.createObjectURL(pdfBlob);
      
      // 使用Print.js打印
      printJS({
        printable: url,
        type: 'pdf',
        showModal: true,
        modalMessage: printerName ? `请在打印对话框中选择 "${printerName}" 打印机` : '请选择打印机',
        onPrintDialogClose: () => {
          URL.revokeObjectURL(url);
        }
      });
      
      return { success: true, fallback: true };
    });
  }

  /**
   * 添加事件监听器
   */
  setupEventListeners() {
    // 避免重复添加事件监听器
    if (this.isEventListenersSetup) {
      console.log('事件监听器已设置，跳过重复设置');
      return;
    }
    
    // 清理现有的事件监听器
    this.cleanupEventListeners();
    
    // 监听打印机变更事件
    const printerChangeHandler = (event) => {
      if (event.detail && event.detail.printer) {
        // 更新本地打印机设置
        this.defaultPrinter = event.detail.printer;
        console.log(`打印机设置已更新: ${this.defaultPrinter}`);
      }
    };
    
    // 监听打印服务连接事件
    const serviceConnectedHandler = (event) => {
      this.isElectronAvailable = true;
      if (event.detail && event.detail.port) {
        // 避免重复显示成功消息，仅在有端口信息时显示
        ElMessage.success(`已连接到打印服务 (${event.detail.host || 'localhost'}:${event.detail.port})`);
      } else {
        // ElMessage.success(`已连接到打印服务${event.detail.host || 'localhost'}:${event.detail.port||'10000'}`);
      }
    };
    
    // 监听打印服务断开事件
    const serviceDisconnectedHandler = () => {
      // 只有在之前是连接状态时才提示断开
      if (this.isElectronAvailable) {
        this.isElectronAvailable = false;
        // 注释掉断开消息，避免频繁提示
        // ElMessage.warning('打印服务已断开');
      }
    };
    if(!this.eventListeners.printerChange){
      window.addEventListener('printerChange', printerChangeHandler);
    }
    if(!this.eventListeners.printerServiceConnected){
      window.addEventListener('printerServiceConnected', serviceConnectedHandler);
    }
    if(!this.eventListeners.printerServiceDisconnected){
      window.addEventListener('printerServiceDisconnected', serviceDisconnectedHandler);
    }
    // 保存事件监听器以便后续清理
    this.eventListeners = [
      { event: 'printerChange', handler: printerChangeHandler },
      { event: 'printerServiceConnected', handler: serviceConnectedHandler },
      { event: 'printerServiceDisconnected', handler: serviceDisconnectedHandler }
    ];
    
    // 设置标志，表示事件监听器已设置
    this.isEventListenersSetup = true;
    console.log('PrintService事件监听器已设置');
  }

  /**
   * 清理事件监听器
   */
  cleanupEventListeners() {
    if (this.eventListeners.length > 0) {
      console.log('正在清理PrintService事件监听器...');
      this.eventListeners.forEach(listener => {
        window.removeEventListener(listener.event, listener.handler);
      });
      this.eventListeners = [];
      this.isEventListenersSetup = false;
    }
  }

  /**
   * 获取打印机列表
   * @returns {Promise<Array>} 打印机列表
   */
  async getPrinters() {
    try {
      const printers = await WMSPrinter.getPrinters();
      this.printerList = printers;
      return printers;
    } catch (error) {
      console.error('获取打印机列表失败:', error);
      ElMessage.error('获取打印机列表失败: ' + (error.message || '未知错误'));
      return [];
    }
  }

  /**
   * 检查打印服务是否可用
   * @returns {boolean} 打印服务是否可用
   */
  isServiceAvailable() {
    return this.isElectronAvailable;
  }

  /**
   * 生成PDF Blob
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @returns {Promise<Blob>} 生成的PDF Blob对象
   */
  async generatePDFBlob(templateData, data, canvasElement) {
    try {
      // 显示加载消息
      const loadingInstance = ElLoading.service({
        text: '正在生成PDF文件...',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      // 使用canvasRenderer的createPdfBlob方法生成PDF Blob
      const pdfBlob = await this.canvasRenderer.createPdfBlob(templateData, data, canvasElement, {
        onLoading: (loading, message) => {
          // 更新加载状态
          if (loadingInstance) {
            loadingInstance.text = message || '正在生成PDF文件...';
          }
          console.log(message);
        },
        onError: (error) => {
          console.error('生成PDF Blob错误:', error);
        },
      });
      
      // 验证生成的Blob
      if (!pdfBlob) {
        throw new Error('未能生成PDF，返回值为空');
      }
      
      if (!(pdfBlob instanceof Blob)) {
        throw new Error('生成的PDF不是有效的Blob对象');
      }
      
      // 确保Blob的MIME类型正确
      let verifiedBlob = pdfBlob;
      const originalType = pdfBlob.type || '';
      
      if (originalType !== 'application/pdf') {
        console.warn(`修正PDF Blob的MIME类型: 从 "${originalType}" 到 "application/pdf"`);
        // 创建一个新的 Blob 对象，指定正确的 MIME 类型
        verifiedBlob = new Blob([pdfBlob], { type: 'application/pdf' });
      }
      
      // 检查 blob 大小，确保有效
      if (verifiedBlob.size === 0) {
        throw new Error('生成的PDF文件大小为0，请检查模板设置');
      }
      
      console.log(`PDF生成成功: 大小 ${Math.round(verifiedBlob.size / 1024)}KB, 类型 ${verifiedBlob.type}`);
      
      // 将 blob 转成 base64 测试是否能正常读取
      try {
        const reader = new FileReader();
        const base64Result = await new Promise((resolve, reject) => {
          reader.onload = () => resolve(reader.result);
          reader.onerror = (e) => reject(new Error(`文件读取失败: ${e.target.error.message || e.message || '未知错误'}`));
          reader.readAsDataURL(verifiedBlob);
        });
        
        if (!base64Result || typeof base64Result !== 'string') {
          throw new Error('无法读取生成的PDF文件');
        }
        
        // 验证base64数据是否包含PDF标记
        if (!base64Result.includes('data:application/pdf;base64,')) {
          console.warn('PDF base64数据的MIME类型可能不正确，尝试修复...');
        }
        
        console.log(`PDF数据验证成功, base64长度: ${base64Result.length}`);
      } catch (e) {
        console.error('PDF文件读取测试失败:', e);
        throw new Error('生成的PDF无法正常读取: ' + e.message);
      }
      
      // 关闭加载提示
      loadingInstance.close();
      
      return verifiedBlob;
    } catch (error) {
      console.error('生成PDF Blob失败:', error);
      ElMessage.error(`生成PDF失败: ${error.message || '未知错误'}`);
      throw error;
    }
  }

  /**
   * 导出模板为图片
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @returns {Promise<string>} 图片的base64数据
   */
  async exportTemplateToImage(templateData, data, canvasElement) {
    try {
      // 显示加载提示
      const loadingInstance = ElLoading.service({
        text: '正在准备图片...',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      
      // 每次都强制重新渲染模板到Canvas，确保在循环中不会使用缓存
      console.log('正在重新渲染模板到Canvas...');
      await this.canvasRenderer.renderTemplateWithData(
        templateData,
        data,
        canvasElement
      );
      console.log('模板已重新渲染到Canvas');
      
      // 导出图片为base64数据
      const imageBase64 = await this.canvasRenderer.exportToImage(null, {
        download: false,
        multiplier: 2,
        onLoading: (loading, message) => {
          if (loadingInstance) {
            loadingInstance.text = message || '正在导出图片...';
          }
        },
        onError: (error) => {
          console.error('导出图片失败:', error);
          ElMessage.error('导出图片失败: ' + (error.message || '未知错误'));
        }
      });
      
      if (!imageBase64) {
        throw new Error('导出图片失败，返回数据为空');
      }
      
      console.log('图片导出成功，数据长度:', imageBase64.length);
      loadingInstance.close();
      
      return imageBase64;
    } catch (error) {
      console.error('导出图片失败:', error);
      ElMessage.error('导出图片失败: ' + (error.message || '未知错误'));
      throw error;
    }
  }

  /**
   * 使用Electron打印PDF
   * @param {Blob} pdfBlob - PDF Blob对象
   * @param {string} printerName - 打印机名称
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async printPdf(pdfBlob, printerName, options = {}) {
    if (!this.isElectronAvailable) {
      throw new Error('Electron打印服务不可用');
    }
    
    // 检查参数
    if (!printerName) {
      throw new Error('未指定打印机');
    }
    
    if (!pdfBlob || !(pdfBlob instanceof Blob)) {
      throw new Error('无效的PDF数据');
    }
    
    if (pdfBlob.size === 0) {
      throw new Error('打印文件大小为0');
    }
    
    // 设置默认打印选项
    const printOptions = {
      silent: true,
      printBackground: true,
      copies: options.copies || 1,
      collate: true,
      ...options
    };
    
    // 保存为默认打印机
    this.saveDefaultPrinter(printerName);
    
    // 日志记录
    console.log('开始打印PDF:', {
      printer: printerName,
      copies: printOptions.copies,
      blobSize: pdfBlob.size,
      blobType: pdfBlob.type
    });
    
    // 使用Electron打印
    const result = await WMSPrinter.printPdf(
      pdfBlob,
      printerName,
      printOptions
    );
    
    console.log('打印结果:', result);
    
    if (!result.success) {
      throw new Error(result.error || '打印失败');
    }
    
    return result;
  }

  /**
   * 使用Electron打印图片
   * @param {string} imageBase64 - 图片base64数据
   * @param {string} printerName - 打印机名称
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async printImage(imageBase64, printerName, options = {}) {
    if (!this.isElectronAvailable) {
      throw new Error('Electron打印服务不可用');
    }
    
    // 检查参数
    if (!printerName) {
      throw new Error('未指定打印机');
    }
    
    if (!imageBase64) {
      throw new Error('无效的图片数据');
    }
    
    // 设置默认打印选项
    const printOptions = {
      silent: true,
      printBackground: true,
      copies: options.copies || 1,
      collate: true,
      ...options
    };
    
    // 保存为默认打印机
    this.saveDefaultPrinter(printerName);
    
    // 使用WMSPrinter.printImage方法，传递正确的参数顺序
    const result = await WMSPrinter.printImage(
      imageBase64, // 第一个参数是图片base64数据
      printerName, // 第二个参数是打印机名称
      printOptions // 第三个参数是打印选项
    );
    
    console.log('图片打印结果:', result);
    
    if (!result.success) {
      throw new Error(result.error || '打印失败');
    }
    
    return result;
  }

  /**
   * 设置打印机选择对话框回调函数
   * @param {Function} showDialogFn - 显示对话框的回调函数
   */
  setShowPrinterDialogCallback(showDialogFn) {
    this.showPrinterDialog = showDialogFn;
  }

  /**
   * 一步完成从模板到PDF打印的过程
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async printTemplate(templateData, data, canvasElement, options = {}) {
    if (this.isPrinting) {
      ElMessage.warning('正在处理打印任务，请稍候再试');
      return;
    }
    
    this.isPrinting = true;
    
    try {
      // 1. 生成PDF Blob
      const pdfBlob = await this.generatePDFBlob(templateData, data, canvasElement);
      
      // 2. 检查Electron打印是否可用
      if (!this.isElectronAvailable) {
        // 降级到浏览器打印
        ElMessage.warning('Electron打印服务不可用，将使用浏览器原生打印');
        
        // 创建临时URL并使用Print.js打印
        const url = URL.createObjectURL(pdfBlob);
        printJS({
          printable: url,
          type: 'pdf',
          showModal: true,
          onPrintDialogClose: () => {
            URL.revokeObjectURL(url);
          }
        });
        
        this.isPrinting = false;
        return { success: true, fallback: true };
      }
      
      // 3. 获取默认打印机或显示打印机选择对话框
      let printerName = options.printer || this.defaultPrinter;
      
      if (!printerName) {
        // 获取打印机列表
        const printers = await this.getPrinters();
        
        if (printers.length === 0) {
          throw new Error('未检测到可用打印机');
        }
        
        // 如果提供了对话框回调函数，使用它来选择打印机
        if (this.showPrinterDialog) {
          const selectedPrinter = await this.showPrinterDialog(printers);
          if (!selectedPrinter) {
            this.isPrinting = false;
            return { success: false, canceled: true };
          }
          printerName = selectedPrinter;
        } else {
          // 没有对话框回调函数，使用第一个打印机
          printerName = printers[0].name;
          ElMessage.info(`使用默认打印机 "${printerName}"`);
        }
      }
      
      // 4. 打印PDF
      const result = await this.printPdf(pdfBlob, printerName, options);
      
      return result;
    } catch (error) {
      console.error('打印模板失败:', error);
      ElMessage.error('打印失败: ' + (error.message || '未知错误'));
      return { success: false, error: error.message || '未知错误' };
    } finally {
      this.isPrinting = false;
    }
  }

  /**
   * 一步完成从模板到图片打印的过程
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @param {Object} options - 打印选项
   * @param {string} [options.fillMode='cover'] - // 填满整个区域，可能裁剪部分内容
   * @param {string} [options.fillMode='stretch'] - // 拉伸填满整个区域
   * @param {string} [options.fillMode='contain'] - // 保持原比例
   * @param {string} [options.fillMode='actual'] - // 按图片实际尺寸打印，不缩放
   * @returns {Promise<Object>} 打印结果
   */
  async printTemplateAsImage(templateData, data, canvasElement, options = {}) {
    if (this.isPrinting) {
      ElMessage.warning('正在处理打印任务，请稍候再试');
      return;
    }
    
    this.isPrinting = true;
    
    try {
      // 重置canvas状态，确保重新渲染
      this.canvasRenderer.isCanvasReady = false;
      
      // 1. 导出模板为图片
      const imageBase64 = await this.exportTemplateToImage(templateData, data, canvasElement);
      
      // 2. 检查Electron打印是否可用
      if (!this.isElectronAvailable) {
        throw new Error('Electron打印服务不可用，无法打印图片');
      }
      
      // 3. 获取默认打印机或显示打印机选择对话框
      let printerName = options.printer || this.defaultPrinter;
      
      if (!printerName) {
        // 获取打印机列表
        const printers = await this.getPrinters();
        
        if (printers.length === 0) {
          throw new Error('未检测到可用打印机');
        }
        
        // 如果提供了对话框回调函数，使用它来选择打印机
        if (this.showPrinterDialog) {
          const selectedPrinter = await this.showPrinterDialog(printers);
          if (!selectedPrinter) {
            this.isPrinting = false;
            return { success: false, canceled: true };
          }
          printerName = selectedPrinter;
        } else {
          // 没有对话框回调函数，使用第一个打印机
          printerName = printers[0].name;
          ElMessage.info(`使用默认打印机 "${printerName}"`);
        }
      }
      
      // 设置打印选项
      const printOptions = {
        silent: true,
        printBackground: true,
        copies: options.copies || 1,
        collate: true,
        ...options
      };
      
      // 4. 打印图片
      const result = await this.printImage(imageBase64, printerName, printOptions);
      
      // if (result.success) {
      //   ElMessage.success(`已使用 ${printerName} 打印图片`);
      // }
      
      return result;
    } catch (error) {
      console.error('打印图片失败:', error);
      ElMessage.error('打印图片失败: ' + (error.message || '未知错误'));
      return { success: false, error: error.message || '未知错误' };
    } finally {
      this.isPrinting = false;
    }
  }

  /**
   * 使用浏览器的内置打印功能打印PDF
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async printPDF(templateData, data, canvasElement, options = {}) {
    if (this.isPrinting) {
      ElMessage.warning('正在处理打印任务，请稍候再试');
      return { success: false, error: '已有打印任务正在进行中' };
    }
    
    this.isPrinting = true;
    
    try {
      // 显示加载提示
      const loadingInstance = ElLoading.service({
        text: '正在准备打印...',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      
      // 使用canvasRenderer直接打印
      await this.canvasRenderer.printTemplateWithData(
        templateData,
        data,
        canvasElement,
        options.filename || '打印文档.pdf',
        {
          onSuccess: () => {
            ElMessage.success('打印成功');
          },
          onError: (error) => {
            console.error('打印失败:', error);
            ElMessage.error('打印失败: ' + error.message);
          },
          onLoading: (loading, message) => {
            if (loading && loadingInstance) {
              loadingInstance.text = message;
            }
          }
        }
      );
      
      // 关闭加载提示
      loadingInstance.close();
      return { success: true };
    } catch (error) {
      console.error('打印PDF失败:', error);
      ElMessage.error('打印失败: ' + error.message);
      return { success: false, error: error.message || '未知错误' };
    } finally {
      this.isPrinting = false;
    }
  }

  /**
   * 直接打印到打印机
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async printDirectToPrinter(templateData, data, canvasElement, options = {}) {
    if (this.isPrinting) {
      ElMessage.warning('正在处理打印任务，请稍候再试');
      return { success: false, error: '已有打印任务正在进行中' };
    }
    
    this.isPrinting = true;
    
    let tempPdfUrl = '';
    
    try {
      // 获取默认打印机
      const printer = options.printer || this.defaultPrinter;
      
      // 显示加载提示
      const loadingInstance = ElLoading.service({
        text: '正在准备发送到打印机...',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      
      // 首先需要生成PDF文件并获取其Blob
      const pdfBlob = await this.generatePDFBlob(
        templateData,
        data,
        canvasElement
      );
      
      if (!pdfBlob) {
        throw new Error('无法生成PDF文件');
      }
      
      // 创建Blob URL
      tempPdfUrl = URL.createObjectURL(pdfBlob);
      
      // 更新加载提示内容
      const printerMsg = printer ? `正在发送到打印机 "${printer}"...` : '正在发送到默认打印机...';
      loadingInstance.text = printerMsg;
      
      // 方法1：使用自定义的方式打开PDF并打印
      try {
        // 打开PDF并直接打印
        const printWindow = window.open(tempPdfUrl);
        if (printWindow) {
          // 等待PDF加载完成
          printWindow.onload = () => {
            try {
              if (printer) {
                console.log(`使用指定打印机: ${printer}`);
                // 由于浏览器安全限制，不能直接修改打印机，但可以在打印对话框中建议用户选择该打印机
                ElMessage.info(`请在打印对话框中选择 "${printer}" 打印机`);
              }
              printWindow.print();
              ElMessage.success('已发送到打印机');
            } catch (innerError) {
              console.error('打印过程出错:', innerError);
              ElMessage.warning('已在新窗口打开PDF，请手动点击打印按钮');
            }
          };
        } else {
          // 弹窗被阻止情况下的处理
          ElMessage.warning('弹窗被浏览器阻止，请允许弹窗或使用浏览器内置PDF查看器打印');
          loadingInstance.close();
          
          // 尝试使用Print.js作为备选方案
          const printJsOptions = {
            printable: tempPdfUrl,
            type: 'pdf',
            showModal: true,
            modalMessage: printer ? `正在准备发送到打印机 "${printer}"...` : '正在准备发送到默认打印机...',
            onPrintDialogClose: () => {
              ElMessage.success('已发送到打印机');
              // 打印完成后释放Blob URL
              URL.revokeObjectURL(tempPdfUrl);
              tempPdfUrl = '';
            },
            onError: (error) => {
              console.error('备选打印方式失败:', error);
              ElMessage.error('打印失败，请尝试下载PDF后手动打印');
              // 提供下载链接
              const downloadLink = document.createElement('a');
              downloadLink.href = tempPdfUrl;
              downloadLink.download = options.filename || '打印文档.pdf';
              downloadLink.click();
            }
          };
          
          // 如果设置了默认打印机，可以尝试通过配置传递（部分浏览器可能支持）
          if (printer) {
            printJsOptions.printerName = printer;
          }
          
          printJS(printJsOptions);
        }
      } catch (printError) {
        console.error('打开PDF窗口失败，尝试使用Print.js:', printError);
        
        // 使用Print.js作为备选方案
        const printJsOptions = {
          printable: tempPdfUrl,
          type: 'pdf',
          showModal: true,
          modalMessage: printer ? `正在发送到打印机 "${printer}"...` : '正在发送到默认打印机...',
          onPrintDialogClose: () => {
            ElMessage.success('已发送到打印机');
            // 打印完成后释放Blob URL
            if (tempPdfUrl) {
              URL.revokeObjectURL(tempPdfUrl);
              tempPdfUrl = '';
            }
          },
          onError: (error) => {
            console.error('发送到打印机失败:', error);
            ElMessage.error('发送到打印机失败: ' + (error.message || '未知错误'));
            
            // 提供下载选项作为最后的备选
            ElMessage.info('您可以下载PDF后手动打印');
            const downloadLink = document.createElement('a');
            downloadLink.href = tempPdfUrl;
            downloadLink.download = options.filename || '打印文档.pdf';
            downloadLink.click();
          }
        };
        
        // 如果设置了默认打印机，可以尝试通过配置传递
        if (printer) {
          printJsOptions.printerName = printer;
        }
        
        printJS(printJsOptions);
      }
      
      // 关闭加载提示
      loadingInstance.close();
      return { success: true };
    } catch (error) {
      console.error('发送到打印机失败:', error);
      ElMessage.error('发送到打印机失败: ' + (error.message || '未知错误'));
      return { success: false, error: error.message || '未知错误' };
    } finally {
      // 清理资源
      if (tempPdfUrl) {
        URL.revokeObjectURL(tempPdfUrl);
      }
      this.isPrinting = false;
    }
  }

  /**
   * 静默打印功能（尽可能减少用户交互）
   * @param {Object} templateData - 模板数据
   * @param {Object} data - 打印内容数据
   * @param {HTMLCanvasElement} canvasElement - Canvas元素
   * @param {Object} options - 打印选项
   * @returns {Promise<Object>} 打印结果
   */
  async silentPrint(templateData, data, canvasElement, options = {}) {
    if (this.isPrinting) {
      ElMessage.warning('正在处理打印任务，请稍候再试');
      return { success: false, error: '已有打印任务正在进行中' };
    }
    
    this.isPrinting = true;
    
    let tempPdfUrl = '';
    
    try {
      // 获取默认打印机
      const printer = options.printer || this.defaultPrinter;
      
      // 显示加载提示
      const loadingInstance = ElLoading.service({
        text: printer ? `正在准备使用 "${printer}" 打印机...` : '正在准备发送到默认打印机...',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      
      // 生成PDF文件并获取其Blob
      const pdfBlob = await this.generatePDFBlob(
        templateData,
        data,
        canvasElement
      );
      
      if (!pdfBlob) {
        throw new Error('无法生成PDF文件');
      }
      
      // 创建Blob URL
      tempPdfUrl = URL.createObjectURL(pdfBlob);
      
      loadingInstance.text = printer ? `正在发送到打印机 "${printer}"...` : '正在发送到默认打印机...';
      
      // 尝试使用iframe打印方法（接近静默打印最好的方法）
      const iframe = document.createElement('iframe');
      iframe.style.display = 'none';
      iframe.style.visibility = 'hidden';
      iframe.style.position = 'fixed';
      iframe.style.right = '0';
      iframe.style.bottom = '0';
      
      document.body.appendChild(iframe);
      
      // 设置iframe加载完成后打印
      iframe.onload = () => { // 使用箭头函数保留this上下文
        try {
          // 延迟触发打印，让PDF完全加载
          setTimeout(() => {
            try {
              if (printer) {
                // 由于浏览器安全限制，只能在打印对话框中显示提示
                ElMessage.info(`请在打印对话框中选择 "${printer}" 打印机`);
              }
              
              // 给予更长的时间让PDF完全渲染
              console.log('PDF已加载，准备打印...');
              iframe.contentWindow.focus();
              
              // 添加一个额外的延迟，确保PDF已完全渲染
              setTimeout(() => {
                try {
                  console.log('执行打印操作...');
                  iframe.contentWindow.print();
                  ElMessage.success(printer ? `已发送到打印机 "${printer}"` : '已发送到默认打印机');
                } catch (printErr) {
                  console.error('打印操作失败:', printErr);
                  // 尝试使用不同的方法打印
                  window.frames['printIframe'] = iframe.contentWindow;
                  window.frames['printIframe'].focus();
                  window.frames['printIframe'].print();
                }
              }, 1500);
            } catch (err) {
              console.error('iframe打印失败:', err);
              // 回落到普通打印方法
              if (tempPdfUrl) {
                URL.revokeObjectURL(tempPdfUrl);
                tempPdfUrl = '';
              }
              
              // 使用备选打印方法
              this.printDirectToPrinter(templateData, data, canvasElement, options);
            }
            
            // 延迟清理iframe，等待打印完成
            setTimeout(() => {
              if (document.body.contains(iframe)) {
                document.body.removeChild(iframe);
              }
            }, 5000); // 延长清理时间，确保打印对话框有足够时间处理
          }, 2000); // 延长初始等待时间，让PDF有更多时间加载
        } catch (e) {
          console.error('静默打印失败:', e);
          if (document.body.contains(iframe)) {
            document.body.removeChild(iframe);
          }
          // 回落到备选打印方法
          this.printDirectToPrinter(templateData, data, canvasElement, options);
        }
      };
      
      // 将PDF加载到iframe
      iframe.src = tempPdfUrl;
      
      // 关闭加载提示
      loadingInstance.close();
      return { success: true };
    } catch (error) {
      console.error('静默打印失败:', error);
      ElMessage.error('发送到打印机失败: ' + (error.message || '未知错误'));
      return { success: false, error: error.message || '未知错误' };
    } finally {
      this.isPrinting = false;
    }
  }

  /**
   * 销毁打印服务实例
   */
  destroy() {
    // 清理事件监听器
    this.cleanupEventListeners();
  }

  /**
   * 断开打印服务连接
   * 在禁用打印服务时调用此方法，确保所有连接都被正确关闭
   */
  disconnect() {
    // 断开WMSPrinter的连接
    WMSPrinter.disconnect();
    
    // 清理事件监听器
    this.cleanupEventListeners();
    
    // 重置状态
    this.isElectronAvailable = false;
    this.printerList = [];
    this.isInitialized = false;
    
    console.log('已断开打印服务连接');
  }

  async _disconnectOnly() {
    // 仅断开WMSPrinter的连接，不清理事件监听器，不重置状态
    WMSPrinter.disconnect();
    console.log('已断开当前连接，准备重新连接');
  }


  /**
   * 设置自定义端口
   * @param {number} port - 端口号
   * @param {string} host - 主机地址，默认为localhost
   * @returns {Promise<boolean>} 连接是否成功
   */
  async setCustomPort(port, host = 'localhost') {
    try {
      // 设置新端口
      WMSPrinter.setCustomPort(port, host);
      // 尝试重新连接
      await WMSPrinter.connect();
      // 更新状态
      this.isElectronAvailable = true;
      this.isInitialized = true;
      
      // 触发连接成功事件 - 修正事件名称，使其与监听器注册的名称一致
      console.log('设置自定义端口', port, host);
      this._triggerEvent('printerServiceConnected', { port, host });
     
      
      return true;
    } catch (error) {
      console.error('连接到自定义端口失败:', error);
      
      // 触发连接失败事件
      this._triggerEvent('printServiceConnectionFailed', { error, port, host });
      
      // 重置初始化状态
      this.isInitialized = false;
      this.isElectronAvailable = false;
      
      return false;
    }
  }

  /**
   * 触发自定义事件
   * @param {string} eventName - 事件名称
   * @param {Object} detail - 事件详情
   * @private
   */
  _triggerEvent(eventName, detail = {}) {
    try {
      const event = new CustomEvent(eventName, { 
        detail,
        bubbles: true,
        cancelable: true
      });
      window.dispatchEvent(event);
    } catch (error) {
      console.error('触发事件失败:', error);
    }
  }
}

// 导出打印服务单例
export default new PrintService(); 